package com.htfyun.serialport.uartservo.AX12_Servo;

import com.htfyun.serialport.uartservo.ServoControlAttr;

public enum AX12_controlTableAttr {

    unknown((byte) 0xff, "unknown", false, false, (byte) 0, (byte)0),

    //rom 区
    mode_sequence_number((byte) 0x00, "模型序号", true, false, (byte) 0x0c, (byte)2),
//    mode_sequence_number_low((byte) 0x00, "模型序号(低字节)", true, false, (byte) 0x0c),
//    mode_sequence_number_high((byte) 0x01, "模型序号(高字节)", true, false, (byte) 0x00),
    firmware_version((byte) 0x02, "固件版本", true, false, (byte) 0x00, (byte)1),
    servo_id((byte) 0x03, "ID", true, true, (byte) 0x01, (byte)1),
    baud_rate((byte) 0x04, "波特率", true, true, (byte) 0x01, (byte)1),
    feedback_delay((byte) 0x05, "反馈延时", true, true, (byte) 0xFA, (byte)1),
    infinite_rotate((byte) 0x06, "无限旋转", true, true, (byte) 0x00, (byte)4),
    min_angle((byte) 0x06, "最小角度", true, true, (byte) 0x00, (byte)2),
//    min_angle_low((byte) 0x06, "最小角度(低)", true, true, (byte) 0x00),
//    min_angle_high((byte) 0x07, "最小角度(高)", true, true, (byte) 0x00),
    max_angle((byte) 0x08, "最大角度", true, true, (byte) 0xff, (byte)2),
//    max_angle_low((byte) 0x08, "最大角度(低)", true, true, (byte) 0xff),
//    max_angle_high((byte) 0x09, "最大角度(高)", true, true, (byte) 0x03),
    reverse1((byte) 0x0a, "保留", false, false, (byte) 0x00, (byte)1),
    temperature_upper_limit((byte) 0x0b, "温度上限", true, true, (byte) 0x55, (byte)1),
    voltage_lower_limit((byte) 0x0c, "电压下限", true, true, (byte) 0x3C, (byte)1),
    voltage_upper_limit((byte) 0x0d, "电压上限", true, true, (byte) 0xBE, (byte)1),
    max_torque((byte) 0x0e, "最大扭矩", true, true, (byte) 0xff, (byte)2),
//    max_torque_low((byte) 0x0e, "最大扭矩(低)", true, true, (byte) 0xff),
//    max_torque_high((byte) 0x0f, "最大扭矩(高)", true, true, (byte) 0xff),
    status_feedback((byte) 0x10, "状态反馈程度", true, true, (byte) 0x02, (byte)1),
    led_warning((byte) 0x11, "LED报警", true, true, (byte) 0x04, (byte)1),
    revert_torque_warning((byte) 0x12, "撤消扭矩警报", true, true, (byte) 0x04, (byte)1),
    reverse2((byte) 0x13, "撤消扭矩警报", false, false, (byte) 0, (byte)1),
    adjust_down((byte) 0x14, "向下校正", true, false, (byte) 0, (byte)2),
//    adjust_down_low((byte) 0x14, "向下校正(低)", true, false, (byte) 0),
//    adjust_down_high((byte) 0x15, "向下校正(高)", true, false, (byte) 0),
    adjust_up((byte) 0x16, "向上校正", true, false, (byte) 0, (byte)2),
//    adjust_up_low((byte) 0x16, "向上校正(低)", true, false, (byte) 0),
//    adjust_up_high((byte) 0x17, "向上校正(高)", true, false, (byte) 0),

    //ram 区
    torque_active((byte) 0x18, "激活扭矩", true, false, (byte) 0, (byte)1),
    led((byte) 0x19, "LED", true, false, (byte) 0, (byte)1),
    clockwise_flexible_magin((byte) 0x1A, "顺时针柔性边距", true, true, (byte) 0, (byte)1),
    anticlockwise_flexible_magin((byte) 0x1B, "逆时针柔性边距", true, true, (byte) 0, (byte)1),
    clockwise_flexible_slope((byte) 0x1C, "顺时针柔性斜率", true, true, (byte) 0, (byte)1),
    anticlockwise_flexible_slope((byte) 0x1D, "逆时针伺服斜率", true, true, (byte) 0, (byte)1),
    set_position((byte) 0x1E, "目标位置(低)", true, true, (byte) 0, (byte)2),
//    set_position_low((byte) 0x1E, "目标位置(低)", true, true, (byte) 0),
//    set_position_high((byte) 0x1F, "目标位置(高)", true, true, (byte) 0),
    moving_speed((byte) 0x20, "运动速度(低)", true, true, (byte) 0, (byte)2),
//    moving_speed_low((byte) 0x20, "运动速度(低)", true, true, (byte) 0),
//    moving_speed_high((byte) 0x21, "运动速度(高)", true, true, (byte) 0),
    torque_limit((byte) 0x22, "扭矩限制(低)", true, true, (byte) 0, (byte)2),
//    torque_limit_low((byte) 0x22, "扭矩限制(低)", true, true, (byte) 0),
//    torque_limit_high((byte) 0x23, "扭矩限制(高)", true, true, (byte) 0),
    current_position((byte) 0x24, "当前位置(低)", true, false, (byte) 0, (byte)2),
//    current_position_low((byte) 0x24, "当前位置(低)", true, false, (byte) 0),
//    current_position_high((byte) 0x25, "当前位置(高)", true, false, (byte) 0),
    current_speed((byte) 0x26, "当前速度(低)", true, false, (byte) 0, (byte)2),
//    current_speed_low((byte) 0x26, "当前速度(低)", true, false, (byte) 0),
//    current_speed_high((byte) 0x27, "当前速度(高)", true, false, (byte) 0),
    current_load((byte) 0x28, "当前负载(低)", true, false, (byte) 0, (byte)2),
//    current_load_low((byte) 0x28, "当前负载(低)", true, false, (byte) 0),
//    current_load_high((byte) 0x29, "当前负载(高)", true, false, (byte) 0),
    current_voltage((byte) 0x2A, "当前电压", true, false, (byte) 0, (byte)1),
    current_temperature((byte) 0x2B, "当前温度", true, false, (byte) 0, (byte)1),
    register_instruction((byte) 0x2C, "寄存器指令", true, true, (byte) 0, (byte)1),
    reverse3((byte) 0x2D, "保留", false, false, (byte) 0x00, (byte)1),
    in_moving((byte) 0x2E, "运动中", true, false, (byte) 0x00, (byte)1),
    lock((byte) 0x2F, "锁定", true, true, (byte) 0x00, (byte)1),
    strike((byte) 0x30, "撞击(低)", true, true, (byte) 0x20, (byte)2),
//    strike_low((byte) 0x30, "撞击(低)", true, true, (byte) 0x20),
//    strike_high((byte) 0x31, "撞击(高)", true, true, (byte) 0x00),

    zero_position((byte) 0x32, "零点偏移", true, true, (byte) 0x0, (byte)2),
    set_zero((byte) 0x34, "设置0点", true, true, (byte) 0x0, (byte)1),
    set_feedback_time((byte) 0x35, "设置主动上报时间", true, true, (byte) 0x0, (byte)1),
    ;

    private final byte address;
    private final String description;
    private final boolean read;
    private final boolean write;
    private final byte initValue;
    private final byte byteCount;//多少字节, 2个或者1个

    AX12_controlTableAttr(byte address, String description, boolean read, boolean write, byte initValue, byte byteCount) {
        this.address = address;
        this.description = description;
        this.read = read;
        this.write = write;
        this.initValue = initValue;
        this.byteCount = byteCount;
    }

    public byte getAddress() {

        return address;
    }

    public byte getByteCount() {
        return byteCount;
    }

    public static ServoControlAttr toServoControlAttr(AX12_controlTableAttr attr) {
        ServoControlAttr servoControlAttr = ServoControlAttr.unknown;
        switch (attr) {
            case firmware_version:
                servoControlAttr = ServoControlAttr.firmware_version;
                break;
            case set_position:
            case current_position:
                servoControlAttr = ServoControlAttr.position;
                break;
            case moving_speed:
            case current_speed:
                servoControlAttr = ServoControlAttr.angular_velocity;
                break;
            case current_load:
                servoControlAttr = ServoControlAttr.load;
                break;
            case min_angle:
                servoControlAttr = ServoControlAttr.angle_area_min;
                break;
            case max_angle:
                servoControlAttr = ServoControlAttr.angle_area_max;
                break;
            case torque_limit:
                servoControlAttr = ServoControlAttr.torque_limit;
                break;
            case torque_active:
                servoControlAttr = ServoControlAttr.torque_active;
                break;
            case current_temperature:
                servoControlAttr = ServoControlAttr.temperature;
                break;
            case in_moving:
                servoControlAttr = ServoControlAttr.move_status;
                break;
            case infinite_rotate:
                servoControlAttr = ServoControlAttr.infinite_rotate_mode;
                break;
            case zero_position:
                servoControlAttr = ServoControlAttr.zero_position;
                break;
            case set_zero:
                servoControlAttr = ServoControlAttr.set_zero;
                break;
            case set_feedback_time:
                servoControlAttr = ServoControlAttr.set_feedback_time;
                break;
            default: break;

        }

        return servoControlAttr;
    }

    public static AX12_controlTableAttr toAX12ControlAttr(ServoControlAttr controlAttr, ServoControlAttr.Instruction instruction) {
        AX12_controlTableAttr attr = unknown;
        switch (controlAttr) {
            case set_feedback_time:
                attr = set_feedback_time;
                break;
            case set_zero:
                attr = set_zero;
                break;
            case zero_position:
                attr = zero_position;
                break;
            case firmware_version:
                attr = firmware_version;
                break;
            case position:
                if (instruction == ServoControlAttr.Instruction.set) {
                    attr = set_position;
                } else {
                    attr = current_position;
                }
                break;
            case angular_velocity:

                attr = moving_speed;
                /*
                if (instruction == ServoControlAttr.Instruction.set) {
                    attr = moving_speed;
                } else {
                    attr = current_speed;
                }*/
                break;
            case load:
                attr = current_load;
                break;
            case angle_area_min:
                attr = min_angle;
                break;
            case angle_area_max:
                attr = max_angle;
                break;
            case torque_limit:
                attr = torque_limit;
                break;
            case torque_active:
                attr = torque_active;
                break;
            case temperature:
                attr = current_temperature;
                break;
            case move_status:
                attr = in_moving;
                break;
            case infinite_rotate_mode:
                attr = infinite_rotate;
                break;
            case unknown:
                default:break;
        }

        return attr;
    }
}
